package com.xiyou.weblog.admin.utils;

import com.xiyou.weblog.admin.config.MinioProperties;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.UUID;

/**
 * @author xiyou
 * @description Minio工具类
 */
@Component
public class MinioUtil {
    private static final Logger log = LoggerFactory.getLogger(MinioUtil.class);
    @Resource
    private MinioClient minioClient;
    @Resource
    private MinioProperties minioProperties;

    public String uploadFile(MultipartFile file) throws Exception {
        // 判断文件是否为空
        if (file == null || file.getSize() == 0) {
            log.error("=> 上传文件异常：文件大小为空...");
            throw new RuntimeException("文件大小不能为空");
        }

        // 文件的原始名称
        String originalFilename = file.getOriginalFilename();
        // 文件的 Content-Type
        String contentType = file.getContentType();

        // 生成存储对象的名称（将 UUID 字符串中的 - 替换成空字符串）
        String key = UUID.randomUUID().toString().replace("-", "");
        // 获取文件的后缀 .jpg .png
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 拼接上文件的后缀，成为要存储的文件名
        String objectName = String.format("%s%s", key, suffix);

        log.info("==> 开始上传文件至 Minio，ObjectName: {}", objectName);

        // 上传文件至Minio
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(objectName)
                .stream(file.getInputStream(),file.getSize(),-1)
                .contentType(contentType)
                .build());

        // 返回文件的访问路径
        String url = String.format("%s/%s/%s", minioProperties.getEndpoint(), minioProperties.getBucketName(), objectName);
        log.info("==> 上传文件至 Minio 成功，访问路径：{}",url);
        return url;

        /*
        我们首先对 MultipartFile 进行了判空，防止上传空的文件。
        然后拿到了该文件的相关属性值，如原始文件名、Content-Type ，
        通过对原始文件名截取出文件后缀，以及通过 UUID 生成一个随机的文件名，
        最终通过 minioClient 客户端的 putObject 方法来上传文件，上传成功后，
        将文件的访问链接拼接好并返回。
         */
    }
}
